package com.github.eclipseace.mybatis.entity.mapping;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.apache.ibatis.mapping.ResultFlag;
import org.apache.ibatis.mapping.ResultMapping;
import org.apache.ibatis.session.Configuration;

import com.github.eclipseace.mybatis.util.Assert;

/**
 * @author eclipseAce
 */
public class MappedEntity {
	public static final String LOCAL_RESULT_MAP_ID = "ResultMap";

	private final Class<?> type;
	private final String table;
	private final String catalog;
	private final String schema;
	private final PropertyMapping idProperty;
	private final List<PropertyMapping> properties;

	public MappedEntity(Class<?> type, String table, String catalog, String schema, PropertyMapping idProperty,
			List<PropertyMapping> properties) {
		Assert.isNotNull(type, "type is null");
		Assert.isNotEmpty(table, "table is null or empty");
		Assert.isNotNull(idProperty, "idProperty is null");

		this.type = type;
		this.table = table;
		this.catalog = catalog;
		this.schema = schema;
		this.idProperty = idProperty;
		this.properties = properties != null ? Collections.unmodifiableList(properties)
				: Collections.<PropertyMapping>emptyList();
	}

	public Class<?> getType() {
		return type;
	}

	public String getTable() {
		return table;
	}

	public String getCatalog() {
		return catalog;
	}

	public String getSchema() {
		return schema;
	}

	public PropertyMapping getIdProperty() {
		return idProperty;
	}

	public List<PropertyMapping> getProperties() {
		return properties;
	}

	public List<PropertyMapping> getAllProperties() {
		List<PropertyMapping> allProperties = new ArrayList<>();
		allProperties.add(idProperty);
		allProperties.addAll(properties);
		return Collections.unmodifiableList(allProperties);
	}

	public String getResultMapId() {
		return type.getName() + "." + LOCAL_RESULT_MAP_ID;
	}

	public List<ResultMapping> getResultMappings(Configuration configuration) {
		List<ResultMapping> resultMappings = new ArrayList<>();
		resultMappings.add(new ResultMapping.Builder(configuration, idProperty.getName())
				.column(idProperty.getColumn())
				.javaType(idProperty.getType())
				.jdbcType(idProperty.getJdbcType())
				.flags(Arrays.asList(ResultFlag.ID))
				.build());
		for (PropertyMapping property : properties) {
			resultMappings.add(new ResultMapping.Builder(configuration, property.getName())
					.column(property.getColumn())
					.javaType(property.getType())
					.jdbcType(property.getJdbcType())
					.build());
		}
		return resultMappings;
	}
}
